//
// Created by LiuYou on 2021/5/19.
//

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <getopt.h>
#include <cstring>

/*
 * -y: year
 * -m: month
 * -d: day
 * -H: hour
 * -M: minute
 * -S: second
 */
int main(int argc, char** argv) {
    // 因为这些小程序的功能都比较简单, 每一句其实都有可能出错, 其实都应该写上if error了怎么办?
    time_t timeStamp = time(nullptr);
    struct tm* pTm = localtime(&timeStamp);
    const int BUF_SIZE = 1024;
    char buf[BUF_SIZE]{};
    strftime(buf, BUF_SIZE, "Now: %Y-%m-%d", pTm);
    std::puts(buf);

    const int FMT_STR_SIZE = 1024;
    char fmtStr[FMT_STR_SIZE]{};
    FILE* fp = stdout;
    for (;;) {
        // 这个i也可以放到for循环外面, 不过放在这里也不影响。
        // 在getopt中规定了6个字符。

        // TODO 注意:
        //  如果字符串中有:那就是:之前的那个字符是带参数的选项;
        //  如果字符前边有-那就是识别非选项的传参
        int i = getopt(argc, argv, "-H:MSy:md ");
        if (i < 0) {
            break;
        }
        switch (i) {
            case 1: {
                // 为了实现先入为主加上了这个if判断。
                if (fp == stdout) {
                    fp = std::fopen(argv[optind - 1], "w");
                    if (fp == nullptr) {
                        std::perror("fopen()");
                        fp = stdout;
                        std::exit(1);
                    }
                }
            }
                break;
            case 'H':
//                std::strncat(fmtStr, "%H ", FMT_STR_SIZE);
                // 改进
                if (std::strcmp(optarg, "12") == 0) {
                    std::strncat(fmtStr, "%I(%P) ", FMT_STR_SIZE);
                } else if (std::strcmp(optarg, "24") == 0) {
                    std::strncat(fmtStr, "%H ", FMT_STR_SIZE);
                } else {
                    std::fprintf(stderr, "Invalid arguments");
                }
                break;
            case 'M':
                // 使用strncat是为了防止数据溢出
                std::strncat(fmtStr, "%M ", FMT_STR_SIZE);
                break;
            case 'S':
                std::strncat(fmtStr, "%S ", FMT_STR_SIZE);
                break;
            case 'y':
//                std::strncat(fmtStr, "%y ", FMT_STR_SIZE);
                // 改进
                if (std::strcmp(optarg, "2") == 0) {
                    std::strncat(fmtStr, "%y ", FMT_STR_SIZE);
                } else if (std::strcmp(optarg, "4") == 0) {
                    std::strncat(fmtStr, "%Y ", FMT_STR_SIZE);
                } else {
                    std::fprintf(stderr, "Invalid arguments");
                }
                break;
            case 'm':
                std::strncat(fmtStr, "%m ", FMT_STR_SIZE);
                break;
            case 'd':
                std::strncat(fmtStr, "%d ", FMT_STR_SIZE);
                break;
            default:
                break;
        }
    }

    std::strncat(fmtStr, "\n", FMT_STR_SIZE);
    strftime(buf, BUF_SIZE, fmtStr, pTm);
    std::fputs(buf, fp);

    if (fp != stdout) {
        std::fclose(fp);
    }

    return 0;
}